package org.kazuhiko.rpg.core;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

import org.kazuhiko.rpg.util.ObjectLoader;
import org.lwjgl.util.vector.Vector3f;

public abstract class Drawable
{
	private Model model;
	
	private String modelLocation;
	
	private int id;
	
	private Vector3f position = new Vector3f();
	private Vector3f rotation = new Vector3f();
	
	private int vboVertexHandle;
	private int vboNormalHandle;
	
	private ArrayList<Flag> flags = new ArrayList<Flag>();
	
	private double mass;
	
	private boolean colliding;
	
	private boolean loaded = false;
	
	private float startFallingHeight;
	private long fallingTime;
	
	public Drawable( String modelLocation, boolean autoload )
	{
		this.modelLocation = modelLocation;
		
		if( autoload )
		{
			loaded = true;
			
			loadModel( modelLocation );
		}
		loaded = false;
	}
	
	private void loadModel( String modelLocation )
	{
		try
		{
			model = ObjectLoader.loadModel( new File( modelLocation ) );
			int[] handles = ObjectLoader.createVBO( model ); 
			vboVertexHandle = handles[0];
			vboNormalHandle = handles[1];
		}
		catch( FileNotFoundException e )
		{
			e.printStackTrace();
		}
		catch( IOException e )
		{
			e.printStackTrace();
		}
	}
	
	public Model getModel()
	{
		return model;
	}
	
	public Vector3f getPosition()
	{
		return position;
	}
	
	public void setPosition( Vector3f position )
	{
		this.position = position;
	}
	
	public Vector3f getRotation()
	{
		return rotation;
	}
	
	public void setRotation( Vector3f rotation )
	{
		this.rotation = rotation;
	}
	
	public float getWidth()
	{
		return model.width;
	}
	
	public float getHeight()
	{
		return model.height;
	}
	
	public float getDepth()
	{
		return model.depth;
	}
	
	public int getVertexHandle()
	{
		return vboVertexHandle;
	}
	
	public int getNormalHandle()
	{
		return vboNormalHandle;
	}
	
	public void addFlag( Flag flag )
	{
		flags.add( flag );
	}
	
	public void removeFlag( Flag flag )
	{
		flags.remove( flag );
	}
	
	public boolean hasFlag( Flag flag )
	{
		return flags.contains( flag );
	}
	
	public double getMass()
	{
		return mass;
	}
	
	public void setMass( double mass )
	{
		this.mass = mass;
	}
	
	public boolean colliding()
	{
		return colliding;
	}
	
	public void colliding( boolean colliding )
	{
		this.colliding = colliding;
		
		if( colliding )
		{
			startFallingHeight = 0;
			fallingTime = 0;
		}
	}
	
	public float getStartFallingHeight()
	{
		return startFallingHeight;
	}
	
	public void setStartFallingHeight( float startFallingHeight )
	{
		this.startFallingHeight = startFallingHeight;
	}
	
	public long getFallingtime()
	{
		return fallingTime;
	}
	
	public void setFallingTime( long fallingTime )
	{
		this.fallingTime = fallingTime;
	}
	
	public int getId()
	{
		return id;
	}
	
	public void setId( int id )
	{
		this.id = id;
	}
	
	public boolean isLoaded()
	{
		return loaded;
	}
	
	public void load()
	{
		loaded = true;
		loadModel( modelLocation );
	}
	
	public abstract void tick();
	public abstract void render();
}
